package com.dmp.common.mybatis;

import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.executor.ReuseExecutor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.mapping.SqlSource;
import org.apache.ibatis.scripting.xmltags.*;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.transaction.jdbc.JdbcTransaction;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @ClassName DataBaseUpdateMethod
 * @Description
 *
 * @author sunzy
 * @date 2016年4月18日 下午3:55:31
 * @version 1.0
 *
 */
public class DyDataBaseInsertMethod implements ExtendMethod {
	private DataSource dataSource;
	// mibatis配置
	private Configuration config;
	private Executor executor;
	private boolean isInited = false;
	private String tableName;
	private String tableCol;
	private String keys;
	private String createTableSql;
	private MappedStatement mStatement;

	
	private static Map<String,String> tableMap = new HashMap<String, String>();
	private String day = "";
	public DataSource getDataSource() {
		return dataSource;
	}

	public void setDataSource(DataSource dataSource) {
		this.dataSource = dataSource;
	}

	@Override
	public void execute(List<Map<String, Object>> context) {
		final List<Map<String, Object>> records = context;
		if (!isInited) {
			synchronized (this) {
				init();
			}
		}

		this.mStatement =  createStatement();
		if (this.mStatement != null) {
			try {
				this.createTable();
				final HashMap<String, List<Map<String, Object>>> parameterObject = new HashMap<String, List<Map<String, Object>>>() {
					private static final long serialVersionUID = -639195294794743440L;
					{
						put("records", records);
					}
				};
				this.createExecutor();
				executor.update(this.mStatement, parameterObject);
				executor.flushStatements();
				executor.commit(true);
			} catch (SQLException e) {
				e.printStackTrace();
			}finally{
				executor.close(true);
				
			}
		}
	}

	public void init() {
		initMibatisConfig();
		createExecutor();
		this.mStatement =  createStatement();
		isInited = true;
	}

	private void initMibatisConfig() {
		config = new Configuration();
		config.setLazyLoadingEnabled(true);
		config.setUseGeneratedKeys(false);
		config.setMultipleResultSetsEnabled(true);
		config.setUseColumnLabel(true);
		config.setDefaultStatementTimeout(5000);
		config.setDefaultFetchSize(100);
	}

	private void createExecutor() {
		executor = new ReuseExecutor(config, new JdbcTransaction(dataSource,
				null, false));
	}

	private MappedStatement createStatement() {
		MappedStatement mStatement = new MappedStatement.Builder(config,
				"insertTo", createDynamicSqlSource(), SqlCommandType.INSERT)
				.build();

		return mStatement;
	}
	


    public void createTable() throws SQLException{
    	String tab = this.tableName + this.day;
    	if(null == tableMap.get(tab)){
    		tableMap.put(tableName, "1");
    		String sql = " CREATE TABLE IF NOT EXISTS " + tab + this.createTableSql;
    		Connection c = dataSource.getConnection();
    		Statement s = c.createStatement();
    		s.execute(sql);
    		s.close();
    		c.close();
    	}
    }
    
	private SqlSource createDynamicCreateSqlSource() {
		StringBuffer prepareSqlBuffer = new StringBuffer("insert into ");
		prepareSqlBuffer.append(this.tableName + this.day);
		return null;
	}

	private DynamicSqlSource createDynamicSqlSource() {
		StringBuffer prepareSqlBuffer = new StringBuffer("insert into ");
		prepareSqlBuffer.append(this.tableName + this.day);
		prepareSqlBuffer.append("(");
		prepareSqlBuffer.append(this.tableCol);
		prepareSqlBuffer.append(") values ");
		
		StringBuffer valueBuffer = new StringBuffer("( ");
		SqlNode staticSqlNode = new TextSqlNode(prepareSqlBuffer.toString());

		String[] keyList = this.keys.split(",");
		for (int i = 0; i < keyList.length; i++) {
			valueBuffer.append("#{item." + keyList[i] + "}");

			if (i < keyList.length - 1) {
				valueBuffer.append(",");
			}
		}
		valueBuffer.append(" ) ");
		
		SqlNode dynamicSqlNode = new TextSqlNode(valueBuffer.toString());
		MixedSqlNode mixedSqlNode = new MixedSqlNode(
				Arrays.asList(dynamicSqlNode));
		ForEachSqlNode forEachSqlNode = new ForEachSqlNode(new Configuration(),
				mixedSqlNode, "records", "index", "item", "", "", ",");
		MixedSqlNode sqlNode = new MixedSqlNode(Arrays.asList(staticSqlNode,
				forEachSqlNode));

		return new DynamicSqlSource(config, sqlNode);
	}

	public String getKeys() {
		return keys;
	}

	public void setKeys(String keys) {
		this.keys = keys;
	}



	@Override
	public void execute(Map<String, Object> context) {

	}

	public String getTableName() {
		return tableName;
	}

	public void setTableName(String tableName) {
		this.tableName = tableName;
	}

	public String getTableCol() {
		return tableCol;
	}

	public void setTableCol(String tableCol) {
		this.tableCol = tableCol;
	}
	
	/** 
	  * @Description 
	  *
	  * @author  suzzy
	  * @date 2016年7月4日 下午3:50:29 
	  *
	  */
	@Override
	public void setDay(String day) {
		this.day = day;
	}
	

	public String getCreateTableSql() {
		return createTableSql;
	}

	public void setCreateTableSql(String createTableSql) {
		this.createTableSql = createTableSql;
	}

}
